/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once


#include "S_键值序列容器.h"

#include "PxPhysicsAPI.h"
#include "vehicle/PxVehicleUtil.h"
#include "vehicle/PxVehicleUtilTelemetry.h"
#include "Px碰撞几何体.h"

#include "../../../S_Physics.h"


#include "车/SampleVehicle_CameraController.h"
#include "车/SampleVehicle_ControlInputs.h"
#include "车/SampleVehicle_GameLogic.h"
#include "车/SampleVehicle_SceneQuery.h"
#include "车/SampleVehicle_VehicleController.h"
#include "车/SampleVehicle_VehicleCooking.h"
#include "车/SampleVehicle_VehicleManager.h"
#include "车/SampleVehicle_WheelQueryResults.h"
//#include "车/SampleVehicleInputEventIds.h"


/*enum {
	DRIVABLE_SURFACE = 0xffff0000,
	UNDRIVABLE_SURFACE = 0x0000ffff
};

enum {
	TIRE_TYPE_NORMAL	= 0,
	TIRE_TYPE_WORN,
	MAX_NUM_TIRE_TYPES
};*/




physx::PxVehicleDrivableSurfaceToTireFrictionPairs* f_创建轮胎摩擦面(const physx::PxMaterial* defaultMaterial);






struct S_Px车轮 : public S_物理体 {
	S_车轮参数				m_属性;

	//physx::PxShape*			m_车轮形状;
	physx::PxMaterial*				m_轮胎材质;
	//physx::PxConvexMesh*			m_车轮网格;
	physx::PxConvexMeshGeometry*	m_车轮网格;
	physx::PxFilterData				m_车轮碰撞过滤;


	S_Px车轮(S_Px物理引擎核心* core, const S_车轮参数& 属性, S_物理几何体& geom, S_物理材质& 材质);
	~S_Px车轮();

	physx::PxVehicleWheelData	f_get轮子模拟参数(const E_车轮ID id);



};










struct S_Px车 : public S_物理体 {
	std::vector<S_Px车轮*>				m_车轮;
	std::vector<physx::PxShape*>		m_车轮形状;

	//S_车体参数							m_车体属性;



	physx::PxRigidDynamic*				m_车体刚体;
	std::vector<physx::PxShape*>		m_车体形状;
	physx::PxFilterData					m_车体碰撞过滤;
	std::vector<float32>				m_悬挂质量;
	//vector<physx::PxConvexMesh*>		m_车体网格;
	physx::PxGeometry*					m_车辆碰撞车辆图形;

	physx::PxVehicleWheelsSimData*		m_轮胎模拟数据;
	physx::PxVehicleDrive4W*			m_车辆驱动;

	physx::PxVehicleDrive4WRawInputData	m_VehicleInputData;

	
	physx::PxVec3						m_探测射线[8];
	uint32								m_碰撞次数;
	float32								m_碰撞距离[8];


	bool								m_是否手柄操作;






	//std::vector<S_物理几何体*>			m_车体碰撞;
	S_车体参数							m_车体参数;
	std::vector<S_车轮参数>				m_车轮参数;








	S_Px车(S_Px物理引擎核心* core, const S_车体参数& 车体参数);
	~S_Px车();


	
	void					f_add构建车体(S_车轮参数* 车轮s, uint8 车轮数量);
	void					f_add构建车轮(S_车轮参数& 车轮);
	void					f_add防撞杠(const E_车轮ID id, float32 刚性 = 10000.0f);

	physx::PxVehicleDriveSimData4W	f_get驱动参数();


	bool				f_检测物体碰撞(physx::PxRigidActor* actor);
	//bool				f_检测静态物体碰撞(physx::PxRigidActor* actor);
	//bool				f_检测动态物体碰撞(physx::PxRigidActor* actor);





	
	

	void f_setLocation(const vec3& loc);
	//void f_setRot(const vec3& loc);
	void f_reset(const vec3& loc);

	vec3				f_get横向和前进速度();
	void				f_加速(const float32 s);
	void				f_倒车(const float32 s);
	void				f_刹车(const float32 s);
	void				f_手刹(const float32 s);
	void				f_转向(const float32 s);
	void				f_加速(const bool s);
	void				f_倒车(const bool s);
	void				f_刹车(const bool s);
	void				f_手刹(const bool s);
	void				f_转向(const int8 s);
	void				f_加减档(const int8 c);



	vec3				f_get速度(physx::PxRigidDynamic& obj);
	vec3				f_get角度(physx::PxRigidDynamic& obj);

	//void				f_setLoc(const vec3& loc);
	//void				f_setVelocity(const vec3& velocity);
	void				f_setLocRot(const vec3& l, const vec3& r);
	void				f_setPos(const vec3& l);
	void				f_setRot(const vec3& r);
	void				f_setVel(const vec3& l);


	inline void*		f_getBody() { return dynamic_cast<PxRigidActor*>(m_车体刚体); }
	inline void*		f_get关联对象() { return m_车体刚体->userData; }
	inline void			f_绑定关联对象(void* data) {
		m_车体刚体->userData = data;
		m_车体形状[0]->userData = data;
	}
	void				f_绑定关联对象(void* data, uint32 id) { m_车轮形状[id]->userData = data; }


	inline void			f_绑定关联对象(std::vector<void*> data) {
		//m_车体刚体->userData = data;
		//m_车体形状[0]->userData = data;
	}















#if PX_DEBUG_VEHICLE_ON
	PxU32					mDebugRenderActiveGraphChannelWheel;
	PxU32					mDebugRenderActiveGraphChannelEngine;
	PxVehicleTelemetryData* mTelemetryData4W;
	PxVehicleTelemetryData* mTelemetryData6W;
#endif

	enum eFocusVehicleType
	{
		ePLAYER_VEHICLE_TYPE_VEHICLE4W = 0,
		ePLAYER_VEHICLE_TYPE_VEHICLE6W,
		ePLAYER_VEHICLE_TYPE_TANK4W,
		ePLAYER_VEHICLE_TYPE_TANK6W,
		eMAX_NUM_FOCUS_VEHICLE_TYPES
	};

	enum
	{
		MAX_NUM_INDEX_BUFFERS = 16
	};
	PxU32							mNbIB;
	PxU32* mIB[MAX_NUM_INDEX_BUFFERS];
	PxU32							mNbTriangles[MAX_NUM_INDEX_BUFFERS];
	PxU32							mRenderMaterial[MAX_NUM_INDEX_BUFFERS];

	PxVehicleDrivableSurfaceType	mVehicleDrivableSurfaceTypes[MAX_NUM_INDEX_BUFFERS];
	PxMaterial* mStandardMaterials[MAX_NUM_INDEX_BUFFERS];
	PxMaterial* mChassisMaterialDrivable;
	PxMaterial* mChassisMaterialNonDrivable;




	// Vehicles
	SampleVehicle_VehicleManager	mVehicleManager;
	//std::vector<RenderMeshActor*>	mVehicleGraphics;
	PxU32							mPlayerVehicle;
	eFocusVehicleType				mPlayerVehicleType;
	PxVehicleDriveTankControlModel::Enum mTankDriveModel;

	SampleVehicle_VehicleController	mVehicleController;


	bool	f_test(S_Px物理引擎核心* core, physx::PxScene* scene, S_车体参数& geom, std::vector<S_车轮参数>& 车轮s);
};




